package com.juzhencms.apps.busi.service;

import java.util.ArrayList;

import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.juzhencms.apps.base.common.config.Config;
import com.juzhencms.apps.base.common.database.DBTable;
import com.juzhencms.apps.base.common.util.IpAddressUtil;
import com.juzhencms.apps.base.common.util.JWTUtil;
import com.juzhencms.apps.base.common.util.MD5Util;
import com.juzhencms.apps.base.common.util.ObjectUtil;
import com.juzhencms.apps.base.common.util.StringUtil;
import com.juzhencms.apps.busi.entity.AdminLoginUser;

import eu.bitwalker.useragentutils.UserAgent;
import lombok.extern.slf4j.Slf4j;
@Service
@Slf4j
//@Transactional(readOnly = true)
public class UserService extends CommonService{
	
	@Autowired
	private AdminMenuService adminMenuService;
	
	@Autowired
	private JWTUtil jwtUtil;
	
	
	@Autowired
	private OrganizationService organizationService;
	
	@Autowired
	private SiteService siteService;
	//用户类型
	public static final int userType=1;
	//cookie的key
	public static final String cookieKey="userToken";
	//缓存前缀
	public static final String cacheKeyPrefix="loginUser.";
	

	/**
	 * 根据用户信息获取操作权限
	 * @param userRecord
	 * @return
	 */
	private Map getUserPermissions(Map userRecord) {
		Map moduleMap=new HashMap();
		
		/*//系统管理员判断
		if(userRecord.get("is_sys")!=null && userRecord.get("is_sys").equals("1")) {
			moduleMap.put("root",1);
			return moduleMap;
		}*/
		
		//获取角色
		if(userRecord.get("role")!=null){
			String[] roleStr=userRecord.get("role").toString().split(",");
			List tmpList=Arrays.asList(roleStr);
			List roleIdList=new ArrayList();
			
			for(int i=0;i<tmpList.size();i++){
				if(tmpList.get(i)!=null && !tmpList.get(i).toString().trim().equals("")){
					roleIdList.add(new Integer(tmpList.get(i).toString()));
				}
			}
			//LogTool.print(roleIdList, this.getClass());
			
			if(roleIdList.size()>0){
				String sqlVarStr="";
				for(int j=0;j<roleIdList.size();j++){
					if(j<roleIdList.size()-1)
						sqlVarStr+="?,";
					else
						sqlVarStr+="?";
				}	
				List roleList=this.getJdbcDao().querySql("select * from "+DBTable.role+" where id in ("+sqlVarStr+")", roleIdList.toArray());
				
				//LogTool.print(roleList, this.getClass());
				
				if(roleList!=null){
					//可操作模块清单
					//List moduleList=new ArrayList();
					
					for(int i=0;i<roleList.size();i++){
						Map role=(Map)roleList.get(i);
						if(role.get("permission")!=null && !role.get("permission").equals("")){
							if(role.get("permission").equals("root")){
								moduleMap.clear();
								moduleMap.put("root",1);
								break;
							}

							List tmpList2=Arrays.asList(role.get("permission").toString().split(","));
							if(tmpList2!=null && tmpList2.size()>0){
								for(int j=0;j<tmpList2.size();j++){
									moduleMap.put(tmpList2.get(j).toString(),1);
								}
							}	
						}
					}
				}
			}
		}
		return moduleMap;
	}
	
	/**
	 * 根据用户信息获取用户菜单
	 * @param userRecord
	 * @return
	 *//*
	private Map getUserMenuData(Map userRecord) {
		Map moduleMap=this.getUserPermissions(userRecord);
		return this.getUserMenuDataByPermissions(moduleMap);
	}*/
	
	
	public Map getUserMenuDataByPermissions(Map moduleMap) {
		return this.getUserMenuDataByPermissions(moduleMap, null);
	}
	
	/**
	 * 根据权限获取用户菜单，第二个参数代表使用站点范围对菜单进行筛选
	 * @param moduleMap
	 * @param siteIdStr
	 * @return
	 */
	
	public Map getUserMenuDataByPermissions(Map moduleMap,String siteIdStr) {
		Map modulePermissions=new LinkedHashMap();
		//log.info("moduleMap====:"+moduleMap);
		//获取角色
		if(moduleMap!=null){
			//避免覆盖全局数据，采用复制方式
			Map permissionsData=ObjectUtil.copy(adminMenuService.getPermissionsData(),Map.class);
			
			modulePermissions=(Map)permissionsData.get("modulePermissions");
			//log.info("modulePermissions:"+JSON.toJSONString(modulePermissions));
			//判断当前环境，仅在开发环境下展示exampleModules（组件展示）菜单
			String env=this.getConfig().getValue("spring.profiles.active");
			if(env!=null && env.toLowerCase().indexOf("dev")<0) {
				modulePermissions.remove("exampleModules");
			}
			
			/*//查询全部站点菜单
			List siteMenuTreeList=adminMenuService.getAllSiteMenuTreeList();
			//log.info("siteIdStr:"+siteIdStr);
			//log.info("siteMenuTreeList:"+JSON.toJSONString(siteMenuTreeList));
			if(siteIdStr!=null) {
				List newSiteMenuTreeList=new ArrayList();
				//在这里根据机构ID获取机构下的站点进行筛选
				if(siteMenuTreeList!=null) {
					for(int i=0;i<siteMenuTreeList.size();i++) {
						Map site=(Map)siteMenuTreeList.get(i);
						Pattern p=Pattern.compile("(^|.+,)"+site.get("id")+"(,.+|$)",Pattern.CASE_INSENSITIVE);//第二个参数代表不区分大小写,可以同时使用多种，例如 Pattern.CASE_INSENSITIVE | Pattern.MULTILINE
						Matcher m=p.matcher(siteIdStr);
						if(m.matches()) {
							newSiteMenuTreeList.add(site);
						}
					}
					siteMenuTreeList=newSiteMenuTreeList;
				}
			}*/
			
			
			//改进方案，只查询有权限的站点
			
			List siteMenuTreeList=adminMenuService.getSiteMenuTreeList(siteIdStr);
			
			
			//log.info("newSiteMenuTreeList:"+JSON.toJSONString(siteMenuTreeList));
			
			Map content=(Map)modulePermissions.get("content");
			content.put("sub", siteMenuTreeList);
			//根据用户权限过滤菜单
			this.makeModuleMenuData(modulePermissions,moduleMap);
				
		}
		
		return modulePermissions;
	}
	
	
	
	
	/**
	 * 根据用户权限过滤菜单,用于后台获取用户菜单
	 * @param data
	 * @return
	 */
	private void makeModuleMenuData(Map data,Map moduleMap){
		
		boolean root=moduleMap.get("root")!=null;
		
		if(data!=null){
			Iterator<Map.Entry<String, Map>> it = data.entrySet().iterator();
			while(it.hasNext()){
	            Map.Entry<String, Map> entry=(Map.Entry<String, Map>)it.next();
	            String key=entry.getKey();
	            
	            if(key.equals("content")) {
	            	continue;
	            }
	            
	            Map moduleMenuData=entry.getValue();
	            
	            String moduleName=moduleMenuData.get("module").toString();
				
				//如果权限中不包含此模块，删除并跳过
				if(!root && moduleMap.get(moduleName)==null){
					it.remove();
					continue;
				}
				
				if(moduleMenuData.get("sub")!=null){
					List subModule=(List)moduleMenuData.get("sub");
					this.makeModuleMenuData(subModule,moduleMap);
				}
	            
	            
	        } 
			
			/*for (Object  key: data.keySet()) {
				Map moduleMenuData=(Map)data.get(key);
				String moduleName=moduleMenuData.get("module").toString();
				
				//如果权限中不包含此模块，删除并跳过
				if(!root && moduleMap.get(moduleName)==null){
					data.remove(key);
					continue;
				}
				
				if(moduleMenuData.get("sub")!=null){
					List subModule=(List)moduleMenuData.get("sub");
					this.makeModuleMenuData(subModule,moduleMap);
				}
			}*/
		}
	}
	
	/**
	 * 根据用户权限过滤菜单,用于后台获取用户菜单
	 * @param data
	 * @return
	 */
	private void makeModuleMenuData(List data,Map moduleMap){
		boolean root=moduleMap.get("root")!=null;
		
		if(data!=null){
			Iterator<Map> it = data.iterator();
			while(it.hasNext()){
				Map moduleMenuData=it.next();
				
				String moduleName=moduleMenuData.get("module").toString();
				//如果权限中不包含此模块，删除并跳过
				if(!root && moduleMap.get(moduleName)==null){
					it.remove();
					continue;
				}
				
				if(moduleMenuData.get("actions")!=null)
					moduleMenuData.put("actions",1);
				if(moduleMenuData.get("sub")!=null){
					List subModule=(List)moduleMenuData.get("sub");
					this.makeModuleMenuData(subModule,moduleMap);
				}
				if(moduleMenuData.get("options")!=null){
					List subModule=(List)moduleMenuData.get("options");
					for(int i=0;i<subModule.size();i++){
						Map option=(Map)subModule.get(i);
						option.put("module", moduleMenuData.get("module")+"."+option.get("option"));
					}
					
					this.makeModuleMenuData(subModule,moduleMap);
				}
			}
			
		}
	}
	
public Map getUserPermissionActions(Map permissions) {
		
		
		// TODO Auto-generated method stub
		Map actions=new HashMap();
		Map modulesAction=adminMenuService.getModulesAction();
		
		for (Object key : permissions.keySet()) {
			String k=key.toString();
			
			//判定是否是栏目
			Pattern p=Pattern.compile("^(\\w+)\\.(.+)$",Pattern.CASE_INSENSITIVE);//第二个参数代表不区分大小写,可以同时使用多种，例如 Pattern.CASE_INSENSITIVE | Pattern.MULTILINE
			Matcher m=p.matcher(k);
			if(m.find()){
				String menu=m.group(1);
				String module=m.group(2);
				
				Map tmpActions=(Map)modulesAction.get(module);
				if(tmpActions!=null){
					//Map newActions=new HashMap();
					for(Object tmpKey : tmpActions.keySet()){
						//添加带有栏目参数的action，用于在控制器中进行栏目权限验证
						actions.put(menu+"."+tmpKey, tmpActions.get(tmpKey));
						
						//存入权限数组，如果存在则合并
						if(actions.get(tmpKey)==null) {
							//actions.put(tmpKey, tmpActions.get(tmpKey));
							//为了不破坏全局数据，这里改用复制的方法
							actions.put(tmpKey, ObjectUtil.copy((List<String>)tmpActions.get(tmpKey), List.class));
							
						}else {
							List<String> subActionOld=(List<String>)actions.get(tmpKey);
							List<String> subActionNew=(List<String>)tmpActions.get(tmpKey);
							
							
							//subActionOld.addAll(subActionNew);//java.lang.ArrayIndexOutOfBoundsException
							//subActionOld = new ArrayList<String>(new LinkedHashSet<>(subActionOld));//java.util.ConcurrentModificationException
							//actions.put(tmpKey, subActionOld);
							
							//改进方法，循环对比，若不存在则插入
							if(subActionNew!=null) {
								for(int i=0;i<subActionNew.size();i++) {
									if(!subActionOld.contains(subActionNew.get(i))) {
										subActionOld.add(subActionNew.get(i));
									}
								}
							}
						}	
					}
					//continue;
				}
			}else {//否则就是功能模块
				String module=k;
				Map tmpActions=(Map)modulesAction.get(module);
				
				if(tmpActions!=null) {
					for (Object tmpKey : tmpActions.keySet()){
						//存入权限数组，如果存在则合并
						if(actions.get(tmpKey)==null) {
							//actions.put(tmpKey, tmpActions.get(tmpKey));
							//为了不破坏全局数据，这里改用复制的方法
							actions.put(tmpKey, ObjectUtil.copy((List<String>)tmpActions.get(tmpKey), List.class));
						}else {
							List<String> subActionOld=(List<String>)actions.get(tmpKey);
							List<String> subActionNew=(List<String>)tmpActions.get(tmpKey);
							//subActionOld.addAll(subActionNew);
							//subActionOld = new ArrayList<String>(new LinkedHashSet<>(subActionOld));
							//actions.put(tmpKey, subActionOld);
							//改进方法，循环对比，若不存在则插入
							if(subActionNew!=null) {
								for(int i=0;i<subActionNew.size();i++) {
									if(!subActionOld.contains(subActionNew.get(i))) {
										subActionOld.add(subActionNew.get(i));
									}
								}
							}
						}	
					}
				}
					
			}
			
			/*//判断是否是功能模块
			Pattern p2=Pattern.compile("^[^\\d].*$",Pattern.CASE_INSENSITIVE);//第二个参数代表不区分大小写,可以同时使用多种，例如 Pattern.CASE_INSENSITIVE | Pattern.MULTILINE
			Matcher m2=p2.matcher(k);
			if(m2.find()){
				String module=m2.group();
				Map tmpActions=(Map)modulesAction.get(module);
				
				if(tmpActions!=null)
					for (Object tmpKey : tmpActions.keySet()){
						//存入权限数组，如果存在则合并
						if(actions.get(tmpKey)==null) {
							actions.put(tmpKey, tmpActions.get(tmpKey));
						}else {
							List<String> subActionOld=(List<String>)actions.get(tmpKey);
							List<String> subActionNew=(List<String>)tmpActions.get(tmpKey);
							subActionOld.addAll(subActionNew);
							subActionOld = new ArrayList<String>(new LinkedHashSet<>(subActionOld));
							actions.put(tmpKey, subActionOld);	
						}	
					}
				continue;
			}*/
			
			
		}
		
		//LogTool.print(actions, this.getClass());
		return actions;
	}
	
	
	public AdminLoginUser makeLoginUser(Map userRecord,Map accessToken) {
		
		
		
		
		/*Map user=new HashMap();
		user.put("id", userRecord.get("id"));
		user.put("user", userRecord.get("user"));
		user.put("pass", userRecord.get("pass"));
		user.put("name", userRecord.get("name"));
		user.put("role", userRecord.get("role"));
		user.put("org_id", userRecord.get("org_id"));
		user.put("token", userRecord.get("token"));
		user.put("img", userRecord.get("img"));
		user.put("loginTime", new Date());
		
		
		//获取登录用户的机构(以及子机构)ID集、获取登录用户的所有父级机构ID集、获取登录用户机构（本机构与子机构）拥有的站点ID集
		String org_ids = "";
		String parent_org_ids = "";
		String org_site_ids = "";
		if(userRecord.get("org_id")!=null && !userRecord.get("org_id").equals("0")) {
			int getOrgId = new Integer(userRecord.get("org_id").toString());
			//本机构与子机构集
			org_ids = organizationService.getOrgIds(getOrgId);
			//父机构ID集
			parent_org_ids = organizationService.getParentOrgIds(getOrgId);
			//机构下站点ID集
			Map getSiteIdsDetail = siteService.getDetail(" GROUP_CONCAT(id) as site_ids ", " org_id in ("+org_ids+") ", null, "", 1);
			if(getSiteIdsDetail != null && getSiteIdsDetail.get("site_ids") != null) {
				org_site_ids = getSiteIdsDetail.get("site_ids").toString();
			}
		}
		user.put("org_ids", org_ids);   
		user.put("parent_org_ids", parent_org_ids);
		user.put("org_site_ids", org_site_ids);
		user.put("is_sys", userRecord.get("is_sys")); 
		
		
		
		Map userPermissions=this.getUserPermissions(user);
		user.put("permissions", userPermissions);
		if(userPermissions.get("root")==null){
			Map userActions=this.getUserPermissionActions(userPermissions);
			Map userMenu=this.getUserMenuDataByPermissions(userPermissions);
			user.put("actions", userActions);
			user.put("userMenu", userMenu);
		}
		return user;*/
		
		
		
		
		
		
		AdminLoginUser loginUser=new AdminLoginUser();
		
		
		loginUser.setAccessTokenId(accessToken.get("id").toString());
		
		loginUser.setId((int)userRecord.get("id"));
		
		if(userRecord.get("user")!=null) {
			loginUser.setUser(userRecord.get("user").toString());
		}
		
		if(userRecord.get("name")!=null) {
			loginUser.setName(userRecord.get("name").toString());
		}
		
		
		if(userRecord.get("pass")!=null || accessToken.get("rand_key")!=null) {
			//合并密码，用于校验签名
			loginUser.setPassword(""+userRecord.get("pass")+accessToken.get("rand_key"));
			
			//生成返回给客户端生成动态签名的密钥
			loginUser.setToken(MD5Util.md5(loginUser.getPassword()));
		}
		
		if(userRecord.get("role")!=null) {		
			loginUser.setRoleIdList(StringUtil.toList(userRecord.get("role").toString()));	
		}
		
		if(userRecord.get("org_id")!=null) {
			loginUser.setOrgId(Integer.parseInt(userRecord.get("org_id").toString()));
		}
		
		
		Map org=this.getJdbcDao().queryRow("select * from "+DBTable.organization+" where del_flag=0 and id=? limit 0,1", new Object[] {userRecord.get("org_id")});
		if(org!=null){
			if(org.get("name")!=null)
				loginUser.setOrgName(org.get("name").toString());
			loginUser.setOrgParentId(new Integer(org.get("parent_id").toString()));
		}
		
		
		if(userRecord.get("img")!=null) {		
			loginUser.setImg(StringUtil.getFileUrl(userRecord.get("img").toString()));
		}
		
		if(userRecord.get("is_sys")!=null && userRecord.get("is_sys").toString().equals("1")) {
			loginUser.setSys(true);
		}else {
			loginUser.setSys(false);
		}
		
		Map userPermissions=this.getUserPermissions(userRecord);
		loginUser.setPermissions(userPermissions);
		
		
		
		//获取登录用户的机构(以及子机构)ID集、获取登录用户的所有父级机构ID集、获取登录用户机构（本机构与子机构）拥有的站点ID集
		String org_ids = "0";
		String parent_org_ids = "0";
		String org_site_ids = "0";
		if(userRecord.get("org_id")!=null && !userRecord.get("org_id").equals("0")) {
			int getOrgId = new Integer(userRecord.get("org_id").toString());
			//本机构与子机构集
			org_ids = organizationService.getOrgIds(getOrgId);
			//log.info("org_ids:"+org_ids);
			//父机构ID集
			parent_org_ids = organizationService.getParentOrgIds(getOrgId);
			//log.info("parent_org_ids:"+parent_org_ids);
			//机构下站点ID集
			Map getSiteIdsDetail = siteService.getDetail(" GROUP_CONCAT(id) as site_ids ", " org_id in ("+org_ids+") ", null, "", 1);
			if(getSiteIdsDetail != null && getSiteIdsDetail.get("site_ids") != null) {
				org_site_ids = getSiteIdsDetail.get("site_ids").toString();
			}else {
				org_site_ids="0";
			}
			//log.info(JSON.toJSONString(getSiteIdsDetail));
		}
		
		loginUser.setParentOrgIds(parent_org_ids);
		
		loginUser.setSubOrgIds(org_ids);
		
		loginUser.setSiteIds(org_site_ids);
		
		//超级管理员不需要action属性来校验权限
		if(userPermissions.get("root")==null){
			Map userActions=this.getUserPermissionActions(userPermissions);
			loginUser.setActions(userActions);
		}
		//第二个参数是使用站点信息对菜单进行筛选，这样机构的超级管理员也只能显示管理机构的站点
		Map userMenu=this.getUserMenuDataByPermissions(userPermissions,org_site_ids);
		loginUser.setUserMenu(userMenu);
		
		loginUser.setLoginTime(new Date());
		return loginUser;
		
	}
	
	public void setLoginCookie(String token,String remember_pwd,HttpServletRequest request,HttpServletResponse response) {
				
		Cookie userTokenCookie = new Cookie(this.cookieKey,token);
		userTokenCookie.setHttpOnly(true);
		if(remember_pwd!=null&& remember_pwd.equals("1")) {
			userTokenCookie.setMaxAge(3600*24*90);//设置其生命周期
		}else {
			userTokenCookie.setMaxAge(0);//设置其生命周期
		}
		userTokenCookie.setPath("/");
		response.addCookie(userTokenCookie);
	}
	
	/*public String getUserToken(Map user) {
		//设置token有效期是90天
        Calendar cal = Calendar.getInstance(); 
        Date datenow = new Date();
        cal.setTime(datenow); 
        cal.add(cal.DATE, 90);
        Date expiresDate=cal.getTime();
        return jwtUtil.getToken(user.get("id").toString(), user.get("pass").toString(), expiresDate);
	}*/
	
	
	public String createUserToken(Map user) {
		
		//设置token有效期是60天
        Calendar cal = Calendar.getInstance(); 
        Date datenow = new Date();
        cal.setTime(datenow);
        cal.add(cal.DATE, 60);
        Date expiresDate=cal.getTime();
		
		//创建随机key
		String randKey=(100+new Random().nextInt(9999999))+"";
		Map accessTokenRecord=new HashMap();
		accessTokenRecord.put("user_type", userType);
		accessTokenRecord.put("user_id",user.get("id"));
		accessTokenRecord.put("rand_key", ""+(new Random().nextInt(9999999)));
		accessTokenRecord.put("create_time",datenow);
		accessTokenRecord.put("refresh_time",datenow);
		accessTokenRecord.put("expire_time",expiresDate);
		
		accessTokenRecord.put("user", user.get("user"));
		accessTokenRecord.put("name", user.get("name"));
		accessTokenRecord.put("ip", IpAddressUtil.getIpAddress(this.getRequest()));
		//获取客户端信息
		UserAgent userAgent = UserAgent.parseUserAgentString(this.getRequest().getHeader("User-Agent"));
		accessTokenRecord.put("client_system",userAgent.getOperatingSystem().toString());
		accessTokenRecord.put("client_browser",userAgent.getBrowser().toString());

		int accesstokenId=this.getJdbcDao().addObj(DBTable.accesstoken, accessTokenRecord);

        String token=jwtUtil.getToken(""+accesstokenId,user.get("id").toString(), expiresDate, ""+user.get("pass")+accessTokenRecord.get("rand_key"));
        
        this.getJdbcDao().updateSql("update "+DBTable.accesstoken+" set sign=? where id=?", new Object[] {token,accesstokenId});
        
        
        return token;
	}
	
	//清除cookie数据
	public void cleanLoginCookie(HttpServletRequest request,HttpServletResponse response) {
		Cookie[] cookies = request.getCookies();//这样便可以获取一个cookie数组
		if(cookies!=null && cookies.length>0) {
			for(Cookie cookie : cookies){
			    String cookieName=cookie.getName();// get the cookie name
			    if(cookieName!=null && cookieName.equals(this.cookieKey)){
			    	cookie.setValue("");
				    cookie.setPath("/");
				    cookie.setMaxAge(0);
				    response.addCookie(cookie);	
			    }
			}
		}
	}
	
	
	public void logout(HttpServletRequest request,HttpServletResponse response) {
		//如果当前在登录状态，清除会话记录
		if(this.getLoginUser()!=null) {
			this.getJdbcDao().updateSql("update "+DBTable.accesstoken+" set status=2 where id=? and status=1",new Object[] {this.getLoginUser().getAccessTokenId()});
		}
		
		
		//清除cookie数据
		cleanLoginCookie(request,response);
		
		
		//清除存储的缓存，以便重新登录可以展示最新的权限数据
		if(this.getLoginUser()!=null) {
			String cacheKey=cacheKeyPrefix+this.getLoginUser().getAccessTokenId();
			this.getCacheSource().getDBCache().evict(cacheKey);
		}
		
		
	}
	
	/**
	 * 清除此用户缓存，包括登录的多个客户端,暂时未使用
	 * @param userId
	 */
	public void cleanUserLoginAccessToken(int userId) {
		//查询可能存在的缓存信息，查询accesstoken表中30分钟以内（已经超出了缓存时间）操作过的记录并清空
		//获取1小时以前的时间
        Calendar cal = Calendar.getInstance(); 
        Date datenow = new Date();
        cal.setTime(datenow);
        cal.add(cal.MINUTE, -30);
        Date beginDate=cal.getTime();
		//查询时包含失效记录，因为有可能是服务端操作数据库，客户端的签名及缓存仍然有效
		List accessTokenList=this.getJdbcDao().querySql("select id from "+DBTable.accesstoken+" where user_id=? and user_type=? and refresh_time>? limit 0,100", new Object[] {userId,userType,beginDate});
		this.getJdbcDao().updateSql("update "+DBTable.accesstoken+" set status=3 where status=1 and user_id=? and user_type=? and refresh_time>?", new Object[] {userId,userType,beginDate});
		if(accessTokenList!=null) {
			for(int i=0;i<accessTokenList.size();i++) {
				Map accessToken=(Map)accessTokenList.get(i);
				String cacheKey=cacheKeyPrefix+accessToken.get("id");
				this.getCacheSource().getDBCache().evict(cacheKey);
			}
		}
	}
	
	
	public AdminLoginUser initLoginUserByCookie(HttpServletRequest request, HttpServletResponse response) {
		//从cookie获取userToken
    	Date timenow=new Date();
		String token = null;
    	Cookie[] cookies = this.getRequest().getCookies();//这样便可以获取一个cookie数组
		if(cookies!=null && cookies.length>0) {
			for(Cookie cookie : cookies){
			    String cookieName=cookie.getName();// get the cookie name
			    if(cookieName!=null && cookieName.equals(this.cookieKey)){
			    	token=cookie.getValue();
			    }
			}
		}
		//log.info("getLoginUserByCookie.token:"+token);
		
		
		if(token!=null) {
			String accessTokenId=jwtUtil.getId(token);
			String userId=jwtUtil.getIssuer(token);
			
			if(userId==null || userId.equals("") || accessTokenId==null || accessTokenId.equals("")) {
				return null;
			}
			
			//下面这部分用缓存注解来做，同一个类，无法使用注解
			
			String cacheKey=cacheKeyPrefix+accessTokenId;
			
			
			
			//在缓存中获取登录用户，若没有则查询后再存入缓存
			AdminLoginUser user=null;
			try {
				user=this.getCacheSource().getDBCache().get(cacheKey, AdminLoginUser.class);
			}catch(Exception e) {
				log.error(e.getMessage(),e);
			}
			
			
			if(user==null) {
				
				
				
				//判断当前会话是否有效
				Map accessToken=this.getJdbcDao().queryRow("select id,rand_key,create_time,refresh_time from "+DBTable.accesstoken+" where id=? and status=1 and expire_time>? limit 0,1", new Object[] {accessTokenId,timenow});
				
				if(accessToken==null) {
					return null;
				}
				
				
				
				/*//查询日志判断半小时内是否有操作，如果没有操作，则视为半小时内无操作自动退出，如果不需要这个功能，注释掉这一段即可============
		        
				//如果accessToken的生成时间在半小时以内，则不需要进行此判断
				Calendar cal = Calendar.getInstance(); 
		        cal.setTime(timenow); 
		        cal.add(cal.MINUTE, -30); //减30分钟
		        
		        //如果accessToken的刷新时间已过30分钟，则查询操作日志
		        Date accessTokenRefreshTime=(Date)accessToken.get("refresh_time");
		        //如果没有刷新时间则使用创建时间
		        if(accessTokenRefreshTime==null ) {
		        	accessTokenRefreshTime=(Date)accessToken.get("create_time");
		        }
		        
		        if(accessTokenRefreshTime.before(cal.getTime())) {
		        	//查询30分钟内的操作日志
					Map lastUserLog=this.getJdbcDao().queryRow("select id from "+DBTable.log+" where access_token_id=? and create_time>? order by create_time desc limit 0,1", new Object[] {accessToken.get("id"),cal.getTime()});
					if(lastUserLog==null) {
						return null;
					}
		        }
		        
				//==========================================
				*/
				
				//更新accessToken的最后使用时间
				this.getJdbcDao().updateSql("update "+DBTable.accesstoken+" set refresh_time=? where id=?", new Object[] {timenow,accessTokenId});
				
				//如果缓存中没有，则查询用户数据存入缓存
				Map userRecord=this.getJdbcDao().queryRow("select * from "+DBTable.user+" where id=? and del_flag=0 and publish=1 limit 0,1", new Object[] {userId});
				if(userRecord==null) {
					return null;
				}
				
				
				
				//给用户数据增加权限及菜单属性
				user=this.makeLoginUser(userRecord,accessToken);
				this.getCacheSource().getDBCache().put(cacheKey, user);
			}
			
			//log.info(JSON.toJSONString(user));

			//验证签名是否正确
			if(user!=null && user.getPassword()!=null && jwtUtil.validateToken(token,user.getPassword().toString())) {
				//因为ehcache缓存数据对象被修改后会直接影响到存储的数据，此处为了避免缓存数据被修改，返回复制的数据
				AdminLoginUser returnUser=ObjectUtil.copy(user, AdminLoginUser.class);
				returnUser.setPassword(null);
				if(returnUser!=null) {
					request.setAttribute(Config.requestLoginUserKey, returnUser);
				}
				return returnUser;				
			}else {
				log.info("验证失败");
				this.cleanLoginCookie(request,response);
			}
		}
		return null;
	}
	
	
	public AdminLoginUser getLoginUser(){
		AdminLoginUser loginUser=(AdminLoginUser)this.getRequest().getAttribute(Config.requestLoginUserKey);
		return loginUser;
	}
	
	

	
	
	/*
	 * getLists：获取(受机构限制)管理员用户列表
	 * @param fields 查询字段默认
	 * @param where String 条件，比如：name like ?
	 * @param whereParamList list 条件参数，如：List whereParamList=new ArrayList();whereParamList.add("%金先生%");
	 * @param orderBy 排序 默认 order by position asc,id asc
	 * @param pageIndex 页码
	 * @param pageSize 每页页数 使用时需与pageIndex都设置 
	 * @param is_not_limit_org 不设置机构限制 默认0设置 1不设置
	 * @return list
	 * 应用：siteService.getAllSite(null, null, null, null, 0, 0,0);
	 */
	public List getLists(String fields, String where, List whereParamList, String orderBy, int pageIndex,
			int pageSize,int is_not_limit_org) {

		// 查询字段
		if (fields == null || fields.equals("")) {
			fields = " * ";
		}

		// 查询条件
		String setWhere = "  where  del_flag=0 ";
		if (where != null && !where.equals("")) {
			setWhere += " and "+where;
		}
		
		//机构限制：系统管理员、超级管理员以外的管理员用户都需要加机构限制
		if(is_not_limit_org == 0) {
			String getLoginUserOrgIds = this.getLoginUser().getSubOrgIds();
			setWhere += " and org_id in ("+getLoginUserOrgIds+") ";
		}

		// 排序：默认ID倒序
		if (orderBy == null || orderBy.equals("")) {
			orderBy = " order by position asc,id asc";
		}

		// 页码，0代表全显示
		String setLimit = "";
		if (pageIndex > 0 && pageSize > 0) {
			setLimit = " limit ?,? ";
			//
			int start=0;
			if(pageIndex>1){
				start=(pageIndex-1)*pageSize;
			}
			whereParamList.add(start);
			whereParamList.add(pageSize);
		}

		// 语句
		String sql = "select " + fields + " from " + DBTable.user + setWhere + orderBy + setLimit;

		// 参数条件
		List dataList = null;
		if (whereParamList != null && whereParamList.size() > 0) {
			dataList = this.getJdbcDao().querySql(sql, whereParamList.toArray());
		} else {
			dataList = this.getJdbcDao().querySql(sql);
		}
		return dataList;

	}
	
	/*
	 * 获取(受机构限制)管理员用户列表
	 */
	public List getLists(String fields) {
		// 查询字段
		if (fields == null || fields.equals("")) {
			fields = " * ";
		}
		return this.getLists(fields, null, null, null, 0, 0,0);
	}
	
	/*
	 * getDetail：获取（机构限制）指定管理员用户信息
	 * @param fields 查询字段默认
	 * @param where String 条件，比如：name like ?
	 * @param whereParamList list 条件参数，如：List whereParamList=new ArrayList();whereParamList.add("%金先生%");
	 * @param orderBy String 排序
	 * @param is_not_limit_org 不设置机构限制 默认0设置 1不设置
	 * @return Map
	 */
	public Map getDetail(String fields, String where, List whereParamList,String orderBy,int is_not_limit_org ) {
		
		// 查询字段
		if (fields == null || fields.equals("")) {
			fields = " * ";
		}

		// 查询条件
		String setWhere = "  where  del_flag=0  ";
		if (where != null && !where.equals("")) {
			setWhere += " and "+where;
		}
		
		//机构限制：系统管理员、超级管理员以外的管理员用户都需要加机构限制
		if(is_not_limit_org == 0){
			String getLoginUserOrgIds = this.getLoginUser().getSubOrgIds();
			/*if( this.getLoginUserPermissions().get("root")==null && !getLoginUserOrgIds.equals("")) {
				setWhere += " and org_id in ("+getLoginUserOrgIds+") ";
			}*/
			
			setWhere += " and org_id in ("+getLoginUserOrgIds+") ";
		}

		// 排序：默认ID倒序
		if (orderBy == null) {
			orderBy = " order by position asc,id asc";
		}

		// 仅查询一条
		String setLimit = " limit 1 ";
		
		// 语句
		String sql = "select " + fields + " from " + DBTable.user + setWhere + orderBy + setLimit;

		// 参数条件
		Map data = new HashMap();
		if (whereParamList != null && whereParamList.size() > 0) {
			data =  this.getJdbcDao().queryRow(sql,whereParamList.toArray());	
		} else {
			data =  this.getJdbcDao().queryRow(sql);	
		}
		return data;
	}
	
	/*
	 * getDetail：获取（机构限制）指定管理员用户信息
	 */
	public Map getDetail(int id,String fields) {
		if(id<=0) {
			return null;
		}
		String where = " id =  "+id;
		return this.getDetail(fields, where,null,null,0);
	}
	
	//判断登录的管理员用户是否为root管理员
	public boolean isRootUser() {
		boolean  result = false;
		if(this.getLoginUser().getPermissions().get("root")!=null){
			result = true;
		}
		return result;
	}
	
	

}
